/*****************************************************
 * 这是一个稀疏矩阵计算库，由于自己之前用eigen库非常不方便，我参考了翀哥代码也复现了一下稀疏矩阵计算库。
 * 当时做numpde大作业多重网格，因为用了稠密矩阵计算，导致速度非常慢，网格大小上不去，破大防
 * 作者：陈冠宇
 * 特别鸣谢：黄文翀
 *****************************************************/
#ifndef SPARSEMATRIX_H
#define SPARSEMATRIX_H

#include "Matrix.h"
#include <vector>

class SparseElement
{
public:
    int j;
    double value;
    SparseElement(const int &_j = 0, const double &_value = 0) : j(_j), value(_value) {}
    ~SparseElement() {}
};

class Triple
{
public:
    int i, j;
    double value;
    Triple() : i(0), j(0), value(0.0) {}
    Triple(const int &_i, const int &_j, const double &_value) : i(_i), j(_j), value(_value) {}
    ~Triple() {}
    bool operator<(const Triple &b) const { return i == b.i && j < b.j || i < b.i; }
};

class SparseMatrix
{
private:
    int n, m; // 稀疏矩阵维数
    int size; // 非零元素个数
    int *row_index;//代表从第几个元素开始是第i行的元素
    SparseElement *elements;//存放所有的非零元素

public:
    SparseMatrix();
    SparseMatrix(const int &_n, const int &_m, std::vector<Triple> &ele);
    SparseMatrix(const SparseMatrix &rhs);
    ~SparseMatrix();
    void clear();
    ColVector operator*(const ColVector &rhs) const;
    friend RowVector operator*(const RowVector &lhs, const SparseMatrix &A);
    SparseMatrix operator+(const SparseMatrix &rhs) const;
    SparseMatrix operator-(const SparseMatrix &rhs) const;
    ColVector wJacobi(const ColVector &x, const ColVector &b, const double &w) const;
    friend std::ostream &operator<<(std::ostream &out, const SparseMatrix &A);
    Matrix toDense() const;
    ColVector LUsolve(const ColVector &b) const;
};

#endif